package com.ygqh.baby.controller.mobile;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.po.ActionOrder;
import com.ygqh.baby.po.ActionOrder.PickWay;
import com.ygqh.baby.po.ActionProduct;
import com.ygqh.baby.po.YgOrderPayment;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.pay.UnifiedOrderResult;
import com.ygqh.baby.service.wechat.notify.PayNotifyData;
import com.ygqh.baby.service.wechat.notify.PayNotifyTemplate;
import com.ygqh.baby.service.wechat.notify.PaySuccessCallBack;
import com.ygqh.baby.utils.SessionUtil;
import com.ygqh.baby.utils.WebUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("mobile/actionorder")
public class ActionOrderController extends BaseController {

	//private final String notify_url = "http://mtest.yiigoo.com/mobile/actionorder/unifiedOrderCallBack.do";
	private final String notify_url = "http://m.yiigoo.com/mobile/actionorder/unifiedOrderCallBack.do";

	@Autowired
	private ActionProductService actionProductService;
	@Autowired
	private ActionOrderService actionOrderService;
	@Autowired
	private YgPayService ygPayService;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private YgOrderPaymentService ygOrderPaymentService;
	@Autowired
	private YgUserService ygUserService;
	@Autowired
	private YgOrderLogService ygOrderLogService;

	@RequestMapping(value = "addProductByBarCode")
	@ResponseBody
	public JSONPObject addProductByBarCode(String barCode, @RequestParam Long actionId, String skuInfos, @RequestParam String callback) {
		ActionProduct product = null;
		;
		if (StringUtils.isNotBlank(barCode)) {
			product = actionProductService.findByBarCode(actionId, barCode);
			if (product == null) {
				return new JSONPObject(callback, Message.error("获取商品信息异常，请联系管理员", null));
			}
		}
		List<ActionProduct> productList = actionProductService.getProductList(product, skuInfos, actionId);
		BigDecimal totalPrice = actionProductService.getTotalPriceFromProductList(productList);
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("totalPrice", totalPrice);
		data.put("product", product);
		return new JSONPObject(callback, Message.success(data));
	}

	@RequestMapping(value = "saveOrder")
	@ResponseBody
	public JSONPObject saveOrder(@RequestParam String skuInfos, @RequestParam Long actionId, @RequestParam(defaultValue = "WeChat") PayType payType,
			@RequestParam(defaultValue = "SinceLift") PickWay pickWay, String remark, @RequestParam String callback) {
		List<ActionProduct> productList = actionProductService.getProductList(null, skuInfos, actionId);
		if (CollectionUtils.isEmpty(productList)) {
			return new JSONPObject(callback, Message.error("提交订单异常，商品信息为空", null));
		}
		if (PickWay.Logistics.equals(pickWay) && StringUtils.isBlank(remark)) {
			return new JSONPObject(callback, Message.error("收货地址信息为空", null));
		}
		BigDecimal totalPrice = actionProductService.getTotalPriceFromProductList(productList);
		Message message = actionOrderService.saveOrder(SessionUtil.getCurrentUser().getId(), productList, totalPrice, payType, OrderStatus.WaitingPay, pickWay,
				remark);
		return new JSONPObject(callback, message);
	}

	@RequestMapping(value = "orderPay")
	@ResponseBody
	public JSONPObject unifiedOrder(Long orderId, @RequestParam(defaultValue = "Small") AppType appType, @RequestParam(defaultValue = "WeChat") PayType payType,
			BigDecimal price, String callback, HttpServletRequest request) throws WeixinException {
		YgUser user = SessionUtil.getCurrentUser();
		String ipAddress = WebUtils.getIpAddr(request).split(",")[0];
		YgUser ygUser = ygUserService.findOpenId(user.getId());
		String openId = ygUser.getSmallOpenId();
		ActionOrder order = actionOrderService.findByOrderId(orderId.toString());
		if (order != null && !order.getOrderStatus().equals(OrderStatus.WaitingPay)) {
			return new JSONPObject(callback, Message.success(true));
		}
		price = order.getTotalMoney();
		Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.OrderPM, new Date());
		UnifiedOrderResult result = ygPayService.unifiedOrder(null, AppType.Small, PayType.WeChat, paymentCode.toString(), price, ipAddress, openId,
				notify_url, "");
		ygOrderPaymentService.addPaymentRecord(BusinessModule.ActionOrder, orderId.toString(), price, paymentCode.toString(), payType, appType,
				result.getPrepayId(), null, result.getPlatformName());
		return new JSONPObject(callback, Message.success(result.getPayRequest()));
	}

	@RequestMapping(value = "unifiedOrderCallBack")
	public void unifiedOrderCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
		response.setHeader("Content-type", "text/html;charset=UTF-8");
		ServletInputStream in = request.getInputStream();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = in.read(buffer)) != -1) {
			out.write(buffer, 0, len);
		}
		String result = new String(out.toByteArray(), "UTF-8");
		ygOrderLogService.addOrderLog(1l, OrderStatus.WaitingSend, "系统", "微信支付回调，回调数据 【" + result + "】;");
		String res = UnifiedOrderCallBack(result);
		ygOrderLogService.addOrderLog(1l, OrderStatus.WaitingSend, "系统", "微信支付回调，返回微信数据 【" + res + "】;");
		logger.debug("\n微信支付回调返回结果：\n" + res);
		out.close();
		in.close();
		response.getWriter().print(res);
	}

	private String UnifiedOrderCallBack(String requestXml) {
		String responseXml = new PayNotifyTemplate(requestXml).execute(new PaySuccessCallBack() {
			@Override
			public void onSuccess(PayNotifyData payNotifyData) {
				new Thread(new Runnable() {
					@Override
					public void run() {
						PayType payType = PayType.WeChat;
						AppType appType = AppType.Small;
						String paymentCode = payNotifyData.getOut_trade_no();
						String transactionId = payNotifyData.getTransaction_id();
						int total_fee = Integer.parseInt(payNotifyData.getTotal_fee());
						BigDecimal totalPrice = new BigDecimal(total_fee).divide(new BigDecimal(100));
						ygOrderLogService.addOrderLog(Long.parseLong(paymentCode), OrderStatus.WaitingPay, "系统,微信支付回调",
								"接收到微信支付回调，这里的orderId是支付流水号。transactionId=" + transactionId);
						// 订单支付成功处理业务逻辑
						doBussnessPaySuccess(paymentCode, transactionId, totalPrice, appType, payType);
					}
				}).start();
			}
		});
		return responseXml;
	}

	private void doBussnessPaySuccess(String paymentCode, String transactionId, BigDecimal totalPrice, AppType appType, PayType payType) {
		YgOrderPayment payment = ygOrderPaymentService.findByPayCode(paymentCode);
		payment.setPaidPrice(totalPrice);
		payment.setPaySuccessTime(new Date());
		payment.setPayType(payType);
		payment.setAppType(appType);
		payment.setTransactionId(transactionId);
		ygOrderPaymentService.writeBackPayment(payment);
		Long orderId = Long.parseLong(payment.getOrderId());
		actionOrderService.updateOrderStatusByPaySuccess(orderId.toString());
	}

	@RequestMapping(value = "findOrderInfoByOrderId")
	@ResponseBody
	public JSONPObject findOrderInfoByOrderId(@RequestParam String orderId, String callback) {
		return new JSONPObject(callback, Message.success(actionOrderService.findByOrderId(orderId)));
	}

	@RequestMapping(value = "findOrderList")
	@ResponseBody
	public JSONPObject findOrderList(@RequestParam Long actionId, OrderStatus orderStatus, String callback) {
		return new JSONPObject(callback,
				Message.success(actionOrderService.findOrderListHasDetail(actionId, SessionUtil.getCurrentUser().getId(), orderStatus)));
	}

}
